#include <stdio.h> 
#include <string.h> 
#include <errno.h> 
#include <limits.h> 
#include <sys/stat.h> 
#include <sys/types.h>   

int main(int argc, char *argv[]) {     
 const char* dest;  //문자열 조작 함수
 struct stat st;  //권한체크를 위한 할당   
 int i;      
 if (argc < 3) {  //인자갯수 저장변수가 3보다 크면      
  fprintf(stderr,"USAGE: %s <source...> <destination>\n", argv[0]);         
  return -1;     
 }      

 /* 대상이 존재하는 경우 */     
 dest = argv[argc - 1];  // 로컬 트랜잭션 모드의 세션을 생성함    
 if (stat(dest, &st)) {         /* 대상은 오류가 누락되지 않는 한 */         
  if (errno != ENOENT) {      //디렉토리나 파일이 존재하지 않음       
   fprintf(stderr, "failed on %s - %s\n", dest, strerror(errno));             
   return -1;         
  }         
  st.st_mode = 0;  //st의 파일타입   
 }      

 for (i = 1; i < argc - 1; i++) {         
  const char *source = argv[i];         
  char fullDest[PATH_MAX + 1 + PATH_MAX + 1];  /* 우리는 "DEST / 소스"를 구축하고, 이름 바꾸기 () pathsize에 실패하자 가정 */         
  
  if (strlen(dest) + 1 + strlen(source) + 1 > sizeof(fullDest)) {             
   fprintf(stderr, "path too long\n");             
   return -1;         
  }         

  strcpy(fullDest, dest);          /* 대상이 디렉토리 인 경우, 소스 파일 이름을 CONCAT */         
  if (S_ISDIR(st.st_mode)) {    //정규 파일이면         
   const char *fileName = strrchr(source, '/');             
   if (fullDest[strlen(fullDest)-1] != '/') {                 
    strcat(fullDest, "/"); //문자열 2개를 받아 첫번째 문자열 뒤에 두번째 문자열을 붙여서 전달해주는 함수            
   }             
  strcat(fullDest, fileName ? fileName + 1 : source);         
  }          /* 이동시키는 시도 */         
  if (rename(source, fullDest)) {       //rename은 파일이름이나 디렉토리이름을 바꾸는 함수      
   fprintf(stderr, "failed on '%s' - %s\n", source, strerror(errno));             
   return -1;  //return -1은 에러가나면 종료 된다는 의미       
  }     
 }      
 return 0; 
}
